﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Expect.VisualStudio.Extensions.Services;
using EnvDTE80;
using EnvDTE;
using System.IO;
    using Expect.Core;
    using Expect.Core.BaseClasses;

namespace Expect.VisualStudio.Extensions
{
    
    public class ExpectItemResolution
    {
        private DateTime _fileTimeStamp = DateTime.Now;

        public string FileName { get; set; }

        public ProjectItem Item { get; set; }

        public List<ClassMap> Classes { get; set; }

        public ClassMap Container { get; set; }

        public CodeClass ContainerClass { get; set; }

        public string ContainerClassName { get; set; }

        public string ContainerClassFullName { get; set; }

        public INameProvider NameProvider { get; private set; }

        //private EnvDTE80.DTE2 _dte;

        public void Resolve(string filename, ProjectItem item, List<ClassMap> classes, INameProvider nameProvider)
        {
            DateTime start = DateTime.Now;
            FileName = filename;
            NameProvider = nameProvider;
            Item = item;
            ContainerClassName = NameProvider.ElementName(Path.GetFileNameWithoutExtension(FileName)) + AbstractSpecificationContainer.ContainerClassSuffix;
            ContainerClassFullName = GetContainerFullname(Item, ContainerClassName);
            Classes = classes;
            
            Container = Classes.FirstOrDefault(c => c.FullName == ContainerClassFullName);
            double duration = (DateTime.Now - start).TotalMilliseconds;
            duration = duration + 1;
       }

        private string GetContainerFullname(ProjectItem currentItem, string containerClassName)
        {
            foreach (ProjectItem item in currentItem.ProjectItems)
            {
                string itemfile = item.FileNames[0].ToLower();
                if (itemfile.ToLower().EndsWith(".expect.cs"))
                {
                    var contclass = item.FileCodeModel.CodeElements.GetClass(containerClassName);
                    if (contclass == null)
                        throw new InvalidOperationException("Container class not found " + containerClassName);
                    
                    return contclass.FullName;                    
                }
            }
            return null;
        }
        
        public ClassMap GetFixtureClassFor(string classname)
        {
            foreach (var classMap in Classes)
            {
                if (classMap.IsFixture && classMap.MapsTo(classname))
                    return classMap;
            }

            return null;
        }

        public IEnumerable<string> ClassHints()
        {
            foreach (var classMap in Classes)
            {
                foreach (var map in classMap.ClassHints)
                {
                    yield return map;
                }
            }
        }
    }
}
